package com.iot08.api.controller;

import com.aliyun.tea.utils.StringUtils;
import com.iot08.api.config.redis.RedisClusterService;
import com.iot08.api.config.redis.RedisFilterService;
import com.iot08.api.constant.Constant;
import com.iot08.api.service.*;
import com.iot08.api.utils.request.ParamHandle;
import com.iot08.api.vo.request.*;
import com.iot08.api.vo.request.base.BaseAccountReqVO;
import com.iot08.common.constant.CacheEnum;
import com.iot08.common.constant.Const;
import com.iot08.common.entity.app.*;
import com.iot08.common.utils.CollectionUtil;
import com.iot08.common.utils.StringUtil;
import com.iot08.common.utils.response.ResponseEnum;
import com.iot08.common.utils.response.ResponseMap;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.util.WebUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;

/**
 * @version 1.0
 * @Description: 聊天群组
 * @time: 2020/12/18 14:19
 * @author: Rock
 */
@Slf4j
@RestController
@RequestMapping("getway/chatGroups")
public class ChatGroupController {

    @Resource
    private ChatGroupService chatGroupService;
    @Resource
    private SingleChatGroupService singleChatGroupService;
    @Resource
    private RedisClusterService redisClusterService;

    @Resource
    private DeviceService deviceService;
    @Resource
    private DeviceDataFlowService deviceDataFlowService;

    @Resource
    private VipMemberService vipMemberService;

    /**
     * 创建聊天群组
     *
     * @param vo
     * @param bindingResult
     * @time: 2020/12/18 15:41
     * @author: Rock
     * @version 1.0
     */
    @PostMapping
    public ResponseMap createChatGroup(@Validated BaseAccountReqVO vo, BindingResult bindingResult) {
        return chatGroupService.createChatGroup(vo);
    }

    /**
     * 查询聊天群信息 (会根据用户返回未读消息)
     * @param groupid
     * @param vo
     * @param bindingResult
     * @time: 2021-10-30 18:39
     * @author: Weichao
     * @version 1.0
     */
    @GetMapping("/{groupid}")
    public ResponseMap getChatGroup(@PathVariable("groupid") String groupid, @Validated ChatGroupGetInfoReqVO vo,
                                    BindingResult bindingResult) {
        if(vo.getGroupType() == 0){
            return chatGroupService.getInfo(groupid, vo);
        }else{
            return singleChatGroupService.getInfo(groupid, vo);
        }

    }

    /**
     * 修改聊天群信息
     *
     * @param groupid
     * @param vo
     * @param image
     * @param bindingResult
     * @time: 2020/12/21 9:56
     * @author: Rock
     * @version 1.0
     */
    @PatchMapping("/{groupid}")
    public ResponseMap updateChatGroup(@PathVariable("groupid") String groupid, MultipartFile image,
                                       @Validated ChatGroupUpdateReqVO vo, BindingResult bindingResult) throws IOException {
        return chatGroupService.updateChatGroup(groupid, vo, image);
    }

    /**
     * 删除聊天群组
     *
     * @param groupid
     * @param vo
     * @param bindingResult
     * @time: 2020/12/21 10:52
     * @author: Rock
     * @version 1.0
     */
    @DeleteMapping("/{groupid}")
    public ResponseMap delChatGroup(@PathVariable("groupid") String groupid,
                                    @Validated BaseAccountReqVO vo, BindingResult bindingResult) {
        return chatGroupService.del(groupid, vo.getOpenid());
    }

    /**
     * 获取聊天群邀请码
     *
     * @param groupid
     * @param vo
     * @time: 2020/12/23 15:16
     * @author: Rock
     * @version 1.0
     */
    @GetMapping("/{groupid}/inviteToken")
    public ResponseMap getInviteToken(@PathVariable("groupid") String groupid,
                                      @Validated ChannelParamReqVO vo, BindingResult bindingResult) {
        return chatGroupService.getInviteToken(groupid, vo);
    }

    /**
     * 批量邀请聊天群成员
     *
     * @param groupid
     * @param vo
     * @param bindingResult
     * @time: 2020/12/23 17:06
     * @author: Rock
     * @version 1.0
     */
    @PostMapping("/{groupid}/accounts")
    public ResponseMap batchAddChatGroupAccount(@PathVariable("groupid") String groupid,
                                                @Validated MembersOpenIdParamReqVO vo, BindingResult bindingResult) {
        return chatGroupService.batchAddChatGroupAccount(groupid, vo);
    }

    /**
     * 邀请聊天群成员
     *
     * @param groupid
     * @param memberOpenid
     * @param vo
     * @param bindingResult
     * @time: 2020/12/23 17:32
     * @author: Rock
     * @version 1.0
     */
    @PostMapping("/{groupid}/accounts/{memberOpenid}")
    public ResponseMap addChatGroupAccount(@PathVariable("groupid") String groupid, @PathVariable("memberOpenid") String memberOpenid,
                                           @Validated ChatGroupAddAccountReqVO vo, BindingResult bindingResult) {
        return chatGroupService.addChatGroupAccount(groupid, memberOpenid, vo);
    }

    /**
     * 删除聊天群成员
     *
     * @param groupid
     * @param memberOpenid
     * @param vo
     * @param bindingResult
     * @time: 2020/12/23 18:01
     * @author: Rock
     * @version 1.0
     */
    @DeleteMapping("/{groupid}/accounts/{memberOpenid}")
    public ResponseMap delChatGroupAccount(@PathVariable("groupid") String groupid, @PathVariable("memberOpenid") String memberOpenid,
                                           @Validated BaseAccountReqVO vo, BindingResult bindingResult) {
        return chatGroupService.delChatGroupAccount(groupid, memberOpenid, vo);
    }

    /**
     * 发送聊天群聊天消息
     *
     * @param groupid
     * @param request
     * @time: 2021/3/6 17:36
     * @author: Rock
     * @version 1.0
     */
    @PostMapping("/{groupid}/message")
    public ResponseMap sendMessage(@PathVariable("groupid") String groupid, HttpServletRequest request) throws IOException {
        //特殊接口处理，ios是form表单传参，安卓是body传参
        Object openid = request.getParameter("openid");
        Object accesstoken = request.getParameter("accesstoken");
        Object type = request.getParameter("type");
        Object duration = request.getParameter("duration");
        Object imei = request.getParameter("imei");
        Integer groupType = 0; // 不传默认是群聊
        if (request.getParameter("groupType") != null) {
            groupType = Integer.valueOf(request.getParameter("groupType"));
        }
        Object content = null;
        String contentType = request.getContentType();
        if (contentType != null && contentType.toLowerCase().startsWith("multipart/")) {
            MultipartHttpServletRequest multipartRequest = WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class);
            content = multipartRequest.getFile("content");
            if (StringUtil.isBlank(content)) {
                content = request.getParameter("content");
            }
            if (StringUtil.isBlank(openid)) {
                Map<String, Object> map = ParamHandle.getParam(request);
                if (StringUtil.isBlank(content)) {
                    content = map.get("content");
                }
                openid = map.get("openid");
                accesstoken = map.get("accesstoken");
                type = map.get("type");
                duration = map.get("duration");
                imei = map.get("imei");
                if(!ObjectUtils.isEmpty(map.get("groupType"))) {
                    groupType = Integer.valueOf(map.get("groupType").toString());
                }
            }
            log.info("content = {}.openid = {}. accesstoken = {}. type = {}.  duration = {}", content, openid, accesstoken, type, duration);
        } else {
            content = request.getParameter("content");
            if (StringUtil.isBlank(openid)) {
                Map<String, Object> map = ParamHandle.getParam(request);
                content = map.get("content");
                openid = map.get("openid");
                accesstoken = map.get("accesstoken");
                type = map.get("type");
                duration = map.get("duration");
                imei = map.get("imei");
                if(!ObjectUtils.isEmpty(map.get("groupType"))) {
                    groupType = Integer.valueOf(map.get("groupType").toString());
                }
            }
        }
        if(content == null || content.toString().length() == 0){
            //不是表情包但是 没有content
            log.error("发送失败，参数异常!,不是表情包但是 没有content");
            return ResponseMap.fail("API.request.parameterError");
        }
        //参数校验
       /* if(!"4".equals(type)){
            if(content == null || content.toString().length() == 0){
                //不是表情包但是 没有content
                log.error("发送失败，参数异常!,不是表情包但是 没有content");
                return ResponseMap.fail("API.request.parameterError");
            }
        }*/
        if (StringUtil.isBlank(openid) || StringUtil.isBlank(accesstoken) || !StringUtil.isNumeric(type)) {
            log.error("发送失败，参数异常!");
            log.info("content = {}. openid = {}. accesstoken = {}. type = {}. imei={}. duration = {}",
                    content, openid, accesstoken, type, imei, duration);
            return ResponseMap.fail(ResponseEnum.STATUS400.getCode(),ResponseEnum.STATUS400.getMsg());
        }
        //accesstoken校验
        String cacheOpenid = redisClusterService.get(CacheEnum.UA.getKey() + accesstoken);
        if (StringUtil.isBlank(cacheOpenid)) {
            log.info("返回无效token, openid={}, accesstoken={}", cacheOpenid, accesstoken, request.getRequestURI());
            return ResponseMap.fail(ResponseEnum.STATUS401.getCode(), ResponseEnum.STATUS401.getMsg());
        }
        if (Constant.PWDCHANGE.equals(cacheOpenid)) {
            return ResponseMap.fail(ResponseEnum.STATUS402.getCode(), "API.request.invalidToken_PWD");
        }
        if (Constant.INVALID.equals(cacheOpenid)) {
            return ResponseMap.fail(ResponseEnum.STATUS402.getCode(), ResponseEnum.STATUS402.getMsg());
        }
        if (StringUtil.isBlank(imei)) {
            if(groupType == 1){
                //单聊
                SingleChatGroup singleChatGroup = singleChatGroupService.findById(groupid);
                imei = singleChatGroup.getImei();
            }else{
                //群聊
                ChatGroup chatGroup = chatGroupService.findById(new ObjectId(groupid));
                if (chatGroup != null && CollectionUtil.isNotEmpty(chatGroup.getDeviceMap())) {
                    for (String key : chatGroup.getDeviceMap().keySet()) {
                        imei = key;
                        break;
                    }
                }
            }
        }
        if (StringUtil.isNotBlank(imei)) {
            //检查预留省电模式
            Device device = deviceService.findById(imei);
            if (device != null && Const.INT_1.equals(device.getPowerModel())) {
                log.info("设备电量低拦截，imei={}", imei);
                return ResponseMap.fail(ResponseEnum.STATUS5003.getCode(), ResponseEnum.STATUS5003.getMsg());
            }
            //检查设备流量限额断网
            DeviceDataFlow deviceDataFlow = deviceDataFlowService.findById(imei);
            if (deviceDataFlow != null && Const.INT_1.equals(deviceDataFlow.getStatus())) {
                log.info("设备网络已断开（已达设定流量套餐），不能使用微聊定位等功能，imei={}", imei);
                return ResponseMap.fail(ResponseEnum.STATUS5005.getCode(), ResponseEnum.STATUS5005.getMsg());
            }
        }
       /* String bqId = request.getParameter("bqId");
        if(Integer.parseInt(type.toString()) == 4){
            if(bqId == null){
                return ResponseMap.fail(ResponseEnum.STATUS400.getCode(), "params bqId is invalid " + type);
            }
        }*/
        //检查用户是否是会员，不是会员时发送消息的内容是否超过限制，没有超过限制则继续发送，超过限制则不允许发送消息
        VipMember vipMember = vipMemberService.queryVipMemberByOpenid(openid.toString());
        if(ObjectUtils.isEmpty(vipMember)) {
            //获取用户发送微聊的上限信息
            int userChatUpLimit = chatGroupService.getUserChatUpLimit();
            log.info("限制次数：{}",userChatUpLimit);
            //获取用户今天已经发送的条数
            int todaySendTimes = chatGroupService.getTodaySendTimes(openid);
            log.info("当天发送次数：{}",todaySendTimes);
            if(todaySendTimes >= userChatUpLimit){
                return ResponseMap.fail("发送失败，您目前不是会员，每天免费发送消息的数量被限制在" + userChatUpLimit + "条以内，如需要享受不受限制的发送消息，请您立即购买会员");
            }
        }
        if(groupType == 1){
            //单聊
            return singleChatGroupService.sendMessage(groupid, openid.toString(), Integer.parseInt(type.toString()),
                    StringUtil.isNumeric(duration) ? Double.parseDouble(duration.toString()) : null,
                    imei == null ? null : imei.toString(), content);
        } else {
            //群聊
            return chatGroupService.sendMessage(groupid, openid.toString(), Integer.parseInt(type.toString()),
                    StringUtil.isNumeric(duration) ? Double.parseDouble(duration.toString()) : null,
                    imei == null ? null : imei.toString(), content);
        }
    }






    /**
     * 获取聊天群聊天消息
     *
     * @param groupid
     * @param vo
     * @param bindingResult
     * @time: 2021/1/14 10:01
     * @author: Rock
     * @version 1.0
     */
    @GetMapping("/{groupid}/message")
    public ResponseMap getMessage(@PathVariable("groupid") String groupid, @Validated ChatGroupGetMessageReqVO vo, HttpServletRequest request) {
        if(vo.getGroupType() == 1) {
            //单聊
            return singleChatGroupService.getMessage(groupid, vo, request);
        }else{
            //群聊
            return chatGroupService.getMessage(groupid, vo, request);
        }
    }

    /**
     * @description 查询聊天群的最后一条记录
     * @author cwj
     * @param [groupid, vo, request]
     * @return com.iot08.common.utils.response.ResponseMap
     * @date @time 2025/7/1 10:33
     **/
    @GetMapping("/{groupid}/lastMessage")
    public ResponseMap getLastMessage(@PathVariable("groupid") String groupid, @Validated ChatGroupMessageGetLastReqVo vo) {
        if(vo.getGroupType() == 1) {
            //单聊
            return singleChatGroupService.getLastMessage(groupid,vo.getOpenid());
        }else{
            //群聊
            return chatGroupService.getLastMessage(groupid,vo.getOpenid());
        }
    }

    /**
     * 清空聊天群聊天消息
     *
     * @param groupid
     * @param vo
     * @param bindingResult
     * @time: 2021/2/22 10:05
     * @author: Rock
     * @version 1.0
     */
    @DeleteMapping("/{groupid}/message")
    public ResponseMap delMessage(@PathVariable("groupid") String groupid, @Validated ChatGroupDelAccountReqVO vo, BindingResult bindingResult) {
        if(vo.getGroupType() == 1) {
            //单聊
            return singleChatGroupService.delMessage(groupid, vo);
        }else{
            //群聊
            return chatGroupService.delMessage(groupid, vo);
        }
    }

}
